package com.cleaningcloud.erp.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.cleaningcloud.common.core.utils.DateUtils;
import com.cleaningcloud.common.core.utils.UniqueIdUtils;
import com.cleaningcloud.common.security.utils.SecurityUtils;
import com.cleaningcloud.erp.domain.*;
import com.cleaningcloud.erp.domain.dto.ErpSaleReturnDto;
import com.cleaningcloud.erp.domain.vo.ErpReturnDetailsVo;
import com.cleaningcloud.erp.domain.vo.ErpSaleReturnVo;
import com.cleaningcloud.erp.mapper.*;
import com.cleaningcloud.common.security.utils.CommunityTypeConversionUtils;
import com.cleaningcloud.erp.utils.ProcureSaleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.cleaningcloud.erp.service.IErpSaleReturnService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 销售退换货Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-10-03
 */
@Service
public class ErpSaleReturnServiceImpl implements IErpSaleReturnService {
    @Autowired
    private ErpSaleReturnMapper erpSaleReturnMapper;

    @Autowired
    private ErpReturnDetailsMapper erpReturnDetailsMapper;

    @Autowired
    private ErpSaleMapper erpSaleMapper;

    @Autowired
    private ErpOutboundMapper erpOutboundMapper;

    @Autowired
    private ErpWarehousingMapper erpWarehousingMapper;

    @Autowired
    private ErpAccountsReceivableMapper erpAccountsReceivableMapper;

    @Autowired
    private ErpAccountsPayableMapper erpAccountsPayableMapper;

    /**
     * 查询销售退换货
     *
     * @param saleReturnId 销售退换货主键
     * @return 销售退换货
     */
    @Override
    public ErpSaleReturnVo selectErpSaleReturnBySaleReturnId(Long saleReturnId) {
        ErpSaleReturnVo saleReturnVo = erpSaleReturnMapper.selectErpSaleReturnBySaleReturnId(saleReturnId);
        for (ErpReturnDetailsVo erpReturnDetailsVo : saleReturnVo.getDetailsList()) {
            erpReturnDetailsVo.setCommodityTypeName(CommunityTypeConversionUtils.conversion(erpReturnDetailsVo.getCommodityTypeName()));
            erpReturnDetailsVo.setCommodityType(CommunityTypeConversionUtils.conversion(erpReturnDetailsVo.getCommodityType()));
        }
        return saleReturnVo;
    }

    /**
     * 查询销售退换货列表
     *
     * @param erpSaleReturn 销售退换货
     * @return 销售退换货
     */
    @Override
    public List<ErpSaleReturnVo> selectErpSaleReturnList(ErpSaleReturn erpSaleReturn) {
        return erpSaleReturnMapper.selectErpSaleReturnList(erpSaleReturn);
    }

    /**
     * 新增销售退换货
     *
     * @param erpSaleReturn 销售退换货
     * @return 结果
     */
    @Override
    @Transactional
    public int insertErpSaleReturn(ErpSaleReturnDto erpSaleReturn) {
        erpSaleReturn.setCreateTime(DateUtils.getNowDate());
        erpSaleReturn.setFlag("Y");
        erpSaleReturn.setCreateId(SecurityUtils.getUserId());
        erpSaleReturn.setCreateName(SecurityUtils.getUsername());
        erpSaleReturn.setApproveStatus(1);
        erpSaleReturn.setSaleReturnOdd("XST" + UniqueIdUtils.generateUniqueId());
        erpSaleReturnMapper.insertErpSaleReturn(erpSaleReturn);
        // 新增销售退还单明细
        batchReturnDetails(erpSaleReturn);
        return 1;
    }

    /**
     * 修改销售退换货
     *
     * @param erpSaleReturn 销售退换货
     * @return 结果
     */
    @Override
    public int updateErpSaleReturn(ErpSaleReturnDto erpSaleReturn) {
        erpSaleReturn.setApproveStatus(1);
        // 根据销售退换货id删除明细
        erpReturnDetailsMapper.deleteByReturnId(erpSaleReturn.getSaleReturnId());
        // 新增销售退还单明细
        batchReturnDetails(erpSaleReturn);
        return erpSaleReturnMapper.updateErpSaleReturn(erpSaleReturn);
    }

    private void batchReturnDetails(ErpSaleReturnDto erpSaleReturn) {
        if (erpSaleReturn.getDetailsList() != null && !erpSaleReturn.getDetailsList().isEmpty()) {
            erpSaleReturn.getDetailsList().forEach(item -> {
                item.setOrderId(erpSaleReturn.getSaleReturnId());
                item.setOrderOdd(erpSaleReturn.getSaleReturnOdd());
                item.setPayType(erpSaleReturn.getPayType());
            });
            erpReturnDetailsMapper.batchReturnDetailsInsert(erpSaleReturn.getDetailsList());
        }
    }

    @Override
    @Transactional
    public int auditErpSaleReturn(ErpSaleReturn saleReturn) {
        ErpSaleReturnVo saleReturnVo = erpSaleReturnMapper.selectErpSaleReturnBySaleReturnId(saleReturn.getSaleReturnId());
        if (saleReturnVo != null) {
            saleReturn.setApproveId(SecurityUtils.getUserId());
            saleReturn.setApproveName(SecurityUtils.getUsername());
            saleReturn.setApproveTime(DateUtils.getNowDate());
            saleReturnVo.setApproveStatus(saleReturn.getApproveStatus());
            // 审核通过时 根据退货商品生成应收款单，退换商品生成应付款和应收款单
            if (saleReturnVo.getApproveStatus() == 3) {
                // 存储退货商品信息
                List<ErpReturnDetailsVo> returnGoodsList = new ArrayList<>();
                // 存储退换商品信息
                List<ErpReturnDetailsVo> returnsList = new ArrayList<>();
                // 查询销售单
                ErpSale erpSale = erpSaleMapper.selectErpSaleBySaleId(saleReturnVo.getSaleId());
                for (ErpReturnDetails erpReturnDetails : saleReturnVo.getDetailsList()) {
                    // 销售商品为退货时 或者退换时 生成应收款单
                    if (erpReturnDetails.getReturnCommodityType() == 1 && (erpReturnDetails.getReturnType() == 1 || erpReturnDetails.getReturnType() == 2)) {
                        // 过滤出销售退换明细中的退换货商品
                        returnGoodsList = saleReturnVo.getDetailsList().stream()
                                .filter(n -> n.getReturnCommodityType() == 1).collect(Collectors.toList());
                    }
                    // 销售单为退换时 生成应收款单
                    if (erpReturnDetails.getReturnCommodityType() == 2) {
                        returnsList = saleReturnVo.getDetailsList().stream()
                                .filter(n -> n.getReturnCommodityType() == 2).collect(Collectors.toList());
                    }
                }
                // 新增应收账款
                if (!returnGoodsList.isEmpty()) {
                    // 计算应收金额
                    BigDecimal oddSumMoney = new BigDecimal("0.0");
                    for (ErpReturnDetailsVo erpReturnDetailsVo : returnGoodsList) {
                        oddSumMoney = oddSumMoney.add(erpReturnDetailsVo.getSalePrice().multiply(BigDecimal.valueOf(erpReturnDetailsVo.getCommodityNumber())));
                    }
                    ErpAccountsPayable erpAccountsPayable = getErpAccountsPayable(saleReturnVo, erpSale, oddSumMoney);
                    erpAccountsPayableMapper.insertErpAccountsPayable(erpAccountsPayable);
                    // 计算应入库总量
                    int answerScheduledReceipt = (int) returnGoodsList
                            .stream()
                            .mapToDouble(ErpReturnDetails::getCommodityNumber)
                            .sum();
                    // 获取仓库ID
                    Long wareId = saleReturnVo.getWareId();
                    // 销售出库单字段赋值
                    ErpWarehousing erpWarehousing = ProcureSaleUtils.setWarehousingFields(erpAccountsPayable, wareId, answerScheduledReceipt);
                    erpWarehousingMapper.insertErpWarehousing(erpWarehousing);
                    // 销售退换货单 退还商品 生成 入库明细
                    List<ErpWarehousingDetails> erpWarehousingDetailsList = ProcureSaleUtils.getErpWarehousingDetailsByProcudeReturn(returnGoodsList, erpWarehousing);
                    if (!erpWarehousingDetailsList.isEmpty()) {
                        erpWarehousingMapper.batchWarehousingDetailsInsert(erpWarehousingDetailsList);
                    }
                }
                // 新增应付账款
                if(!returnsList.isEmpty()){
                    // 计算应收金额
                    BigDecimal oddSumMoney = new BigDecimal("0.0");
                    for (ErpReturnDetailsVo erpReturnDetailsVo : returnsList) {
                        oddSumMoney = oddSumMoney.add(erpReturnDetailsVo.getCostPrice().multiply(BigDecimal.valueOf(erpReturnDetailsVo.getCommodityNumber())));
                    }
                    ErpAccountsReceivable erpAccountsReceivable = getErpAccountsReceivable(saleReturnVo, erpSale, oddSumMoney);
                    erpAccountsReceivableMapper.insertErpAccountsReceivable(erpAccountsReceivable);
                    // 计算应出库总量
                    int answerScheduledReceipt = (int) returnsList.stream().mapToDouble(ErpReturnDetails::getCommodityNumber).sum();
                    // 获取仓库ID
                    Long wareId = saleReturnVo.getWareId();
                    // 销售出库单字段赋值
                    ErpOutbound erpOutbound = ProcureSaleUtils.setOutboundFields(erpAccountsReceivable, wareId, answerScheduledReceipt);
                    erpOutboundMapper.insertErpOutbound(erpOutbound);
                    // 销售退换货单 退换商品 生成 出库明细
                    List<ErpOutboundDetails> erpOutboundDetailsList = ProcureSaleUtils.getErpOutboundDetailsByProcudeReturn(returnsList, erpOutbound);
                    if (!erpOutboundDetailsList.isEmpty()) {
                        erpOutboundMapper.batchOutboundDetailsInsert(erpOutboundDetailsList);
                    }

                }
            } else {
                saleReturnVo.setRejectReason(saleReturn.getRejectReason());
                saleReturnVo.setRejectTime(DateUtils.getNowDate());
            }
            return erpSaleReturnMapper.updateErpSaleReturn(saleReturn);
        } else {
            throw new RuntimeException("销售退换货单查询失败！");
        }


    }


    /**
     * 床脚应付账款单
     *
     * @param erpProcudeReturn
     * @param procudeReturn
     * @param erpProcure
     * @return
     */
    private static ErpAccountsPayable getErpAccountsPayable(ErpSaleReturnVo erpSaleReturnVo, ErpSale erpSale, BigDecimal oddSumMoney) {
        ErpAccountsPayable erpAccountsPayable = new ErpAccountsPayable();
        erpAccountsPayable.setOddType(2);
        erpAccountsPayable.setOddNo(erpSaleReturnVo.getSaleReturnOdd());
        erpAccountsPayable.setBusinessId(erpSale.getCustomerId());
        erpAccountsPayable.setOddDate(DateUtils.getNowDate());
        erpAccountsPayable.setOddStatus(0);
        erpAccountsPayable.setOddSumMoney(oddSumMoney);
        erpAccountsPayable.setFlag("Y");
        return erpAccountsPayable;
    }


    /**
     * 新增应收账款单
     *
     * @param erpProcudeReturn
     * @param procudeReturn
     * @param erpProcure
     * @return
     */
    private static ErpAccountsReceivable getErpAccountsReceivable(ErpSaleReturnVo erpSaleReturnVo, ErpSale erpSale, BigDecimal oddSumMoney) {
        ErpAccountsReceivable erpAccountsReceivable = new ErpAccountsReceivable();
        erpAccountsReceivable.setOddType(3);
        erpAccountsReceivable.setOddNo(erpSaleReturnVo.getSaleReturnOdd());
        erpAccountsReceivable.setBusinessId(erpSale.getCustomerId());
        erpAccountsReceivable.setOddDate(DateUtils.getNowDate());
        erpAccountsReceivable.setOddStatus(0);
        erpAccountsReceivable.setOddSumMoney(oddSumMoney);
        erpAccountsReceivable.setFlag("Y");
        return erpAccountsReceivable;
    }

    /**
     * 批量删除销售退换货
     *
     * @param saleReturnIds 需要删除的销售退换货主键
     * @return 结果
     */
    @Override
    public int deleteErpSaleReturnBySaleReturnIds(Long[] saleReturnIds) {
        return erpSaleReturnMapper.deleteErpSaleReturnBySaleReturnIds(saleReturnIds);
    }

    /**
     * 删除销售退换货信息
     *
     * @param saleReturnId 销售退换货主键
     * @return 结果
     */
    @Override
    public int deleteErpSaleReturnBySaleReturnId(Long saleReturnId) {
        return erpSaleReturnMapper.deleteErpSaleReturnBySaleReturnId(saleReturnId);
    }
}
